package com.nn.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nn.R;
import com.nn.constents.SystemConstants;
import com.nn.domain.dto.AddArticle;
import com.nn.entity.Article;
import com.nn.entity.ArticleTag;
import com.nn.entity.Category;
import com.nn.mapper.ArticleMapper;
import com.nn.service.ArticleService;
import com.nn.service.ArticleTagService;
import com.nn.service.CategoryService;
import com.nn.utils.BeanCopyUtils;
import com.nn.vo.ArticleDetailVO;
import com.nn.vo.ArticlePage;
import com.nn.vo.HotArticleVo;
import com.nn.vo.PageVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文章表(Article)表服务实现类
 *
 * @author 年年
 * @since 2022-11-11 16:13:52
 */

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Resource
    private CategoryService categoryService;

    @Resource
    private ArticleMapper  articleMapper;
    /**
     * 查询热门文章前十
     * @return
     */
    @Override
    public R hotArticleList() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL).orderByDesc(Article::getViewCount);
        //只查询十条
        Page<Article> page = new Page<>(1,10);
        page(page, queryWrapper);
        List<Article> articles =page.getRecords();

        //处理返回给前端的数据
        //TODO bean拷贝   ----调用工具类
        List<HotArticleVo> result = BeanCopyUtils.copyBeanList(articles, HotArticleVo.class);

        return R.okResult(result);
    }


    /**
     * 文章分页查询
     * @param pageNum
     * @param pageSize
     * @param categoryId
     * @return
     */
    @Override
    public R articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        //TODO categoryId 有可能没有, 状态是正式发布的,对istop排序
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(categoryId!=null&&categoryId>0,Article::getCategoryId,categoryId)
                .eq(Article::getStatus,SystemConstants.ARTICLE_STATUS_NORMAL)
                .orderByDesc(Article::getIsTop).orderByDesc(Article::getCreateTime);
        Page<Article> page = new Page<>(pageNum,pageSize);
        page(page,queryWrapper);

        List<ArticlePage> result = BeanCopyUtils.copyBeanList(page.getRecords(), ArticlePage.class);
        for (ArticlePage info : result){
            Category category = categoryService.getById(info.getCategoryId());
            info.setCategoryName(category.getName());
        }
        PageVO pageVO = new PageVO(result,page.getTotal());
        return R.okResult(pageVO);
    }

    /**
     * 展示文章详细内容
     * @param id
     * @return
     */
    @Override
    public R findIdByArticle(Long id) {
        Article article = getById(id);
        ArticleDetailVO articleDetailVO = BeanCopyUtils.copyBean(article, ArticleDetailVO.class);
        Long categoryId = articleDetailVO.getCategoryId();
        Category category = categoryService.getById(categoryId);
        if(category!=null)
            articleDetailVO.setCategoryName(category.getName());
        return R.okResult(articleDetailVO);

    }




    /**
     * 更新文章浏览量
     * @return
     */
    @Transactional
    @Override
    public R updateViewCount(Long id) {
        articleMapper.updateViewCountById(id);
        return R.okResult();
    }


    /**
     * 文章查询
     * @param pageNum
     * @param pageSize
     * @param title
     * @param summary
     * @return
     */
    @Override
    public R pagetList(Integer pageNum, Integer pageSize, String title, String summary) {
        Page<Article> page = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(title!=null,Article::getTitle,title)
                .like(summary!=null,Article::getSummary,summary)
                .eq(Article::getDelFlag,0);
        page(page,queryWrapper);
        List<ArticlePage> pageInfo = BeanCopyUtils.copyBeanList(page.getRecords(), ArticlePage.class);
        for (ArticlePage articlePage : pageInfo) {
            articlePage.setViewCount(null);
            articlePage.setThumbnail(null);
        }
        PageVO pageVO = new PageVO(pageInfo,page.getTotal());
        return R.okResult(pageVO);
    }


    /**
     * 删除文章
     * @param ids
     * @return
     */
    @Override
    public R deleteArticleByid(List<Integer> ids) {
        getBaseMapper().deleteBatchIds(ids);
        //删除对应分类信息
        getBaseMapper().selectBatchIds(ids);
        return R.okResult();
    }

    /**
     * 根据id获取文章信息
     * @param id
     * @return
     */
    @Override
    public R getArticleInfoByID(Long id) {
        Article article = getBaseMapper().selectById(id);
        //将标签id传进article
        List<Long> tagIdList = articleTagService.selectTagIdList(id);
        article.setTags(tagIdList);
        return R.okResult(article);
    }


    /**
     * 更新文章信息
     * @param article
     * @return
     */
    @Override
    public R updateArticle(Article article) {
        if(!StringUtils.hasText(article.getTitle()))
            throw new RuntimeException("文章标题不能为空");
        if(article.getCategoryId()==null)
            throw new RuntimeException("请选择文章分类");
        getBaseMapper().updateById(article);
        //添加博客和标签的关联关系
        List<Long> tagId = article.getTags();
        List<ArticleTag> atList = new ArrayList<>();
         for (Long id : tagId){
            ArticleTag at = new ArticleTag(article.getId(),id);
            atList.add(at);
         }

        //查询数据库
            for (ArticleTag at : atList){
                articleTagService.removeById(at.getArticleId());
            }
            articleTagService.saveBatch(atList);
        return R.okResult();
    }

    @Resource
    private ArticleTagService articleTagService;

    /**
     * 添加文章
     * @param article
     * @return
     */
    @Override
    @Transactional
    public R add(AddArticle article) {
        Article articleInfo = BeanCopyUtils.copyBean(article,Article.class);
        save(articleInfo);
        List<ArticleTag> articleTags = article.getTags().stream()
                .map(tagId->new ArticleTag(article.getId(),tagId))
                .collect(Collectors.toList());
        for (ArticleTag at :articleTags){
            at.setArticleId(articleInfo.getId());
        }
        //添加博客和标签的关联关系
        articleTagService.saveBatch(articleTags);
        return R.okResult();
    }
}

